import { DynamicAreaSchema } from '../schema/schema';
import { BuilderHTMLElement } from '@farris/designer-element';
import { DynamicAreaProp } from '../property/property-config';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { ComponentFactoryResolver, Injector } from '@angular/core';
import { BsModalService } from '@farris/ui-modal';
import { CreateDynamicItemComponent, DynamicAreaItemBuildInfo } from './editor/create-dynamic-item/create-dynamic-item.component';
import { DomService } from '@farris/designer-services';
import { DgControl } from '../../../../utils/dg-control';

/**
 * 动态区域，可以添加预制模板
 */
export default class FdDynamicAreaComponent extends FdContainerBaseComponent {

    /* 标识每个标签页项label的key值 */
    get tabPageLinkKey(): string {
        return `tabNav-${this.key}`;
    }
    /* 标识标签页项删除图标的key值 */
    get tabPageRemoveLinkKey(): string {
        return `tabRemove-${this.key}`;
    }
    /* 标识添加标签页图标的key值 */
    get addIconLinkKey(): string {
        return `tabAdd-${this.key}`;
    }
    /* 标识每个标签页项主体的key值 */
    get tabPageBodyKey(): string {
        return `tabBody-${this.key}`;
    }

    /** 当前选中标签页id */
    selectedTabPageId: string;

    /** 标签页项的组件实例 */
    tabPageComponents: any[];

    constructor(component: any, options: any) {
        super(component, options);

        this.customToolbarConfigs = [
            {
                id: 'addDynamicItem',
                title: '新增面板',
                icon: 'f-icon f-icon-add',
                click: (e) => {
                    e.stopPropagation();
                    this.addDynamicItem();
                }
            }
        ];
    }

    getDefaultSchema(): any {
        return DynamicAreaSchema;
    }

    getTemplateName(): string {
        return 'DynamicArea';
    }

    /**
     * 判断是否可以接收拖拽新增的子级控件
     */
    canAccepts(sourceElement: BuilderHTMLElement): boolean {
        return false;
    }

    /**
     * 组装属性面板配置数据
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options.designerHost;
        const prop: DynamicAreaProp = new DynamicAreaProp(serviceHost, this.viewModelId, this.componentId);
        const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
        return propertyConfig;
    }


    init(): void {
        this.components = [];
        this.tabPageComponents = [];
        let firstTabPageId = '';
        // this.tabPages = [];
        this.component.contents.forEach((tabPage, index) => {
            this.tabPageComponents[index] = [];
            tabPage.contents = tabPage.contents || [];
            tabPage.contents.forEach((comp) => {
                const tabPageComponent: any = this.createComponent(comp, this.options, null);
                this.tabPageComponents[index].push(tabPageComponent);
            });
            firstTabPageId = firstTabPageId ? firstTabPageId : tabPage.id;
        });

        this.selectedTabPageId = this.component.selectedTabId || firstTabPageId;
    }

    render(): any {

        return super.render(this.renderTemplate('DynamicArea', {
            tabComponents: this.tabPageComponents.map(tabPage => this.renderComponents(tabPage)),
            selectedTabPageId: this.selectedTabPageId,
            tabPageLinkKey: this.tabPageLinkKey,
            tabPageRemoveLinkKey: this.tabPageRemoveLinkKey,
            addIconLinkKey: this.addIconLinkKey,
            tabPageBodyKey: this.tabPageBodyKey
        }));
    }


    attach(element: any): any {
        this.loadRefs(element, {
            [this.tabPageLinkKey]: 'multiple',
            [this.tabPageRemoveLinkKey]: 'multiple',
            [this.tabPageBodyKey]: 'multiple',
            [this.addIconLinkKey]: 'single',
        });

        const superAttach: any = super.attach(element);

        // 注册面板项切换事件
        this.refs[this.tabPageLinkKey].forEach((tabLink, index) => {
            this.addEventListener(tabLink, 'click', (event) => {
                event.preventDefault();
                event.stopPropagation();
                this.setTabPage(index);

            });
        });

        // 注册面板项删除事件
        this.refs[this.tabPageRemoveLinkKey].forEach((tabLink, index) => {
            this.addEventListener(tabLink, 'click', (event) => {
                event.preventDefault();
                event.stopPropagation();
                this.removeDynamicItem(index);
            });
        });

        // 注册面板项新增事件
        this.addEventListener(this.refs[this.addIconLinkKey], 'click', (event) => {
            event.preventDefault();
            event.stopPropagation();
            this.addDynamicItem();
        });

        // 加载每个面板项下面的子组件
        this.refs[this.tabPageBodyKey].forEach((tab, index) => {
            this.attachComponents(tab, this.tabPageComponents[index], this.component.contents[index].contents);
        });

        return superAttach;
    }

    /**
     * 切换标签页
     * @param index 标签页索引
     */
    private setTabPage(index: number) {
        if (
            !this.tabPageComponents ||
            !this.tabPageComponents[index]
        ) {
            return;
        }

        this.selectedTabPageId = this.component.contents[index].id;

        this.redraw();
    }

    /**
     * 删除面板项
     * @param index 待删除面板索引
     */
    private removeDynamicItem(index: number) {
        const dynamicItem = this.component.contents[index];
        const serviceHost = this.options.designerHost;
        const msgService = serviceHost.getService('MessagerService');
        const domService = serviceHost.getService('DomService');
        const refreshFormService = serviceHost.getService('RefreshFormService');


        msgService.question('确定删除【' + dynamicItem.title + '】下的所有组件吗？', () => {

            // 移除内部组件
            this.checkComponentInDynamicItem(dynamicItem, domService);
            // 移除面板项
            this.component.contents.splice(index, 1);
            // 修改选中面板
            if (this.selectedTabPageId === dynamicItem.id) {
                this.component.selectedTabId = this.component.contents.length ? this.component.contents[0].id : '';
            }
            // 触发页面刷新
            refreshFormService.refreshFormDesigner.next();

        });
    }
    /**
     * 面板中包含Component组件，需要移除相关的Component和ViewModel
     * @param rawDynamicItem 待移除的面板
     */
    private checkComponentInDynamicItem(rawDynamicItem: any, domService: DomService) {
        const componentRefs = [];

        this.selectComponentRefNode(rawDynamicItem, componentRefs);

        if (componentRefs.length) {
            componentRefs.forEach(ref => {
                const cmp = domService.getComponentById(ref.component);

                domService.deleteComponent(ref.component);
                domService.deleteViewModelById(cmp.viewModel);
            });

        }
    }

    /**
     * 根据指定的条件遍历查找节点
     * @param rootNode 容器节点
     * @param predict 条件
     */
    selectComponentRefNode(rootNode: any, componentRefs: any[]) {
        if (!rootNode) {
            return;
        }
        if (rootNode.type === DgControl.ComponentRef.type) {
            componentRefs.push(rootNode);
        }
        if (rootNode.contents) {
            for (const item of rootNode.contents) {
                this.selectComponentRefNode(item, componentRefs);
            }
        }
        return;
    }
    /**
     * 新增面板项
     */
    private addDynamicItem() {
        // 动态创建相关的服务需要从designerHost中获取
        const serviceHost = this.options.designerHost;
        const resolver = serviceHost.getService('ComponentFactoryResolver') as ComponentFactoryResolver;
        const injector = serviceHost.getService('Injector') as Injector;
        const modalService = serviceHost.getService('ModalService') as BsModalService;
        const refreshFormService = serviceHost.getService('RefreshFormService');

        const compFactory = resolver.resolveComponentFactory(CreateDynamicItemComponent);
        const compRef = compFactory.create(injector);

        const modalConfig = {
            title: '新增动态面板',
            width: 900,
            height: 600,
            showButtons: true,
            buttons: compRef.instance.btns,
            resizable: false
        };


        const modalPanel = modalService.show(compRef, modalConfig);
        compRef.instance.cancel.subscribe(() => {
            modalPanel.close();
        });

        compRef.instance.save.subscribe((data) => {
            if (data) {
                this.addNodesToForm(data);

                refreshFormService.refreshFormDesigner.next();
            }

            modalPanel.close();
        });

    }
    /**
     * 创建新面板
     * @param data 面板构造信息
     */
    private addNodesToForm(data: DynamicAreaItemBuildInfo) {
        const { dynamicItem, components, viewModels } = data;
        if (!dynamicItem) {
            return;
        }
        const serviceHost = this.options.designerHost;
        const domService = serviceHost.getService('DomService');
        this.component.contents.push(dynamicItem);

        if (components && components.length) {
            components.forEach(c => {
                domService.addComponent(c);
            });

        }
        if (viewModels && viewModels.length) {
            viewModels.forEach(v => {
                domService.addViewModel(v);
            });

        }

        // 默认选中新增的标签页
        this.setTabPage(this.component.contents.length - 1);
    }
}
